import {ApolloClient} from 'apollo-client'
import {createHttpLink} from 'apollo-link-http'
import {InMemoryCache, NormalizedCacheObject} from 'apollo-cache-inmemory'
import {setContext} from 'apollo-link-context'
import fetch from 'isomorphic-unfetch'
import {withClientState} from 'apollo-link-state'
import state from './apollo-state'
import {ApolloLink} from 'apollo-link'

let apolloClient: ApolloClient<NormalizedCacheObject>

// Polyfill fetch() on the server (used by apollo-client)
if (!process.browser) {
    global.fetch = fetch
}
type GetToken = () => string

function create(initialState: any, option: { getToken: GetToken }): ApolloClient<NormalizedCacheObject> {
    const {getToken} = option
    const httpLink = createHttpLink(
        {
            uri: process.env.API_SERVER_URL || 'http://localhost:3000/graphql',
            fetch
        })

    const authLink = setContext((_, {headers}) => {
        const token = getToken() || window.localStorage.getItem('token')//localStorage只为测试（要删）
        return {
            headers: {
                ...headers,
                authorization: token ? `Bearer ${token}` : null
            }
        }
    })
    const cache = new InMemoryCache()
    const stateLink = withClientState({cache, ...state});
    // console.log(333, stateLink, cache)
// NormalizedCacheObject
    return new ApolloClient({
        connectToDevTools: process.browser,
        ssrMode: !process.browser, // Disables forceFetch on the server (so queries are only run once)
        link: ApolloLink.from([authLink, stateLink, httpLink]),
        cache //: cache.restore(initialState || {})
    })
}

export default function initApollo(initialState: any, options: { getToken: GetToken }) {
    // Make sure to create a new client for every server-side request so that data
    // isn't shared between connections (which would be bad)
    if (!process.browser) {
        return create(initialState, options)
    }

    // Reuse client on the client-side
    if (!apolloClient) {
        apolloClient = create(initialState, options)
    }

    return apolloClient
}